/*
 *Copyright © 2015 zhaorongbao
 *招融宝
 *http://zhaorongbao.com
 *All rights reserved.
 */
package com.hanhai.zrb.api.biz.service.impl;

import java.io.IOException;
import java.util.Random;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.hanhai.common.cache.Cache;
import com.hanhai.common.exception.ValidateCodeSendException;
import com.hanhai.common.result.ValidateCodeSendResult;
import com.hanhai.zrb.api.biz.service.CheckcodeTemplateService;
import com.hanhai.zrb.api.biz.service.SMSCodeService;
import com.hanhai.zrb.api.biz.service.ValidateCodeSendService;
import com.hanhai.zrb.model.common.CheckcodeTemplate;
import com.hanhai.zrb.model.common.ValidateCodeSend;
import com.hanhai.zrb.model.common.ValidateCodeSend.BizTypeEnum;
import com.hanhai.zrb.model.common.ValidateCodeSend.SendTypeEnum;

@Service("validateCodeSendService")
public class ValidateCodeSendServiceImpl implements ValidateCodeSendService {
	// 内部用的验证码
	private static final String INNER_CHECKCODE = "zrb888";

	private final Logger logger = LoggerFactory
			.getLogger(getClass());

	@Resource
	private Cache defaultCache;

	String ValidateCodePrefix = "ValidateCode_";

	@Resource
	private CheckcodeTemplateService checkcodeTemplateService;
	
	@Resource
	private SMSCodeService sMSCodeService;
	
	@Override
	public ValidateCodeSendResult createAndSendCheckCode(
			ValidateCodeSend validateCodeSend) {
		ValidateCodeSendResult result = new ValidateCodeSendResult();

		try {
			// 获取校验码
			String checkCode = this.getCheckCode(validateCodeSend);
			logger.debug("生成的校验码：" + checkCode);
			
			// 获取内容模板
			String configName = validateCodeSend.getBizType().name();
			CheckcodeTemplate contentTemplate =  checkcodeTemplateService.findCheckcodeTemplate(configName);
			// 替换模板内容
			String content = contentTemplate.getContent().replaceFirst("\\$\\{checkCode\\}",
					checkCode);
			String subject = contentTemplate.getSubject();
			// 发送邮件或短信校验码
			doSend(validateCodeSend.getSendType(),
					validateCodeSend.getSendIdentity(), content, subject);
			String bizName = getBizName(validateCodeSend);
			// 写入缓存
			saveCache(validateCodeSend.getSendIdentity(), bizName, checkCode,
					validateCodeSend.getEffectMinute());
		} catch (ValidateCodeSendException e) {
			logger.error(
					"ValidateCodeSendService.createAndSendCheckCode  excute exception",
					e);
			result.setResultCode(e.getCode());
			return result;
		} catch (Exception e) {
			result.setResultCode(ValidateCodeSendResult.ResultCodeEnum.System_exception
					.name());
			logger.error(
					"ValidateCodeSendService.createAndSendCheckCode  excute exception",
					e);
			return result;
		}
		result.setSuccess(true);
		return result;
	}

	

	@Override
	public ValidateCodeSendResult check(ValidateCodeSend validateCodeSend,
			String code) {

		ValidateCodeSendResult result = new ValidateCodeSendResult();
		// 全局验证码，测试用
		if (StringUtils.equals(code, INNER_CHECKCODE)) {
			result.setSuccess(true);
			return result;
		}
		String bizName;
		try {
			bizName = getBizName(validateCodeSend);
		} catch (ValidateCodeSendException e) {
			logger.error("ValidateCodeSendService.check  excute exception", e);
			result.setResultCode(e.getCode());
			return result;
		}

		Object o = getCache(validateCodeSend.getSendIdentity(), bizName);
		if (o == null) {
			result.setResultCode(ValidateCodeSendResult.ResultCodeEnum.ExpiredOrNoExist
					.name());
			return result;
		}
		String cacheCode = (String) o;
		if (!StringUtils.equals(cacheCode, code)) {
			result.setResultCode(ValidateCodeSendResult.ResultCodeEnum.Code_match_error
					.name());
			return result;
		}
		result.setSuccess(true);
		removeCache(validateCodeSend.getSendIdentity(), bizName);
		return result;
	}

	private String getBizName(ValidateCodeSend validateCodeSend)
			throws ValidateCodeSendException {
		String bizName;
		BizTypeEnum bizType = validateCodeSend.getBizType();
		if (bizType == BizTypeEnum.Other) {
			bizName = validateCodeSend.getOtherBizName();
		} else {
			bizName = bizType.name();
		}
		return bizName;
	}

	@Deprecated
	private String getContentTemplate(ValidateCodeSend validateCodeSend)
			throws ValidateCodeSendException {
		String contentTemplate;
		BizTypeEnum bizType = validateCodeSend.getBizType();
		if (bizType == BizTypeEnum.Other) {
			contentTemplate = validateCodeSend.getContentTemplate();
		} else {
			contentTemplate = bizType.getContent();
		}
		return contentTemplate;
	}

	private String getCheckCode(ValidateCodeSend validateCodeSend)
			throws ValidateCodeSendException {
		String code;
		SendTypeEnum sendTypeEnum = validateCodeSend.getSendType();

		if (sendTypeEnum == SendTypeEnum.SMS) {
			code = createMobileCode();
		} else if (sendTypeEnum == SendTypeEnum.EMAIL) {
			code = createEmailCode();
		} else {
			code = createMobileCode();
		}
		return code;
	}

	private void saveCache(String identity, String bizTypeName,
			String checkCode, int effectMinute) {
		defaultCache.add(ValidateCodePrefix + bizTypeName + "_" + identity,
				checkCode, effectMinute * 60);
	}

	private Object getCache(String identity, String bizTypeName) {
		return defaultCache.getValue(ValidateCodePrefix + bizTypeName + "_"
				+ identity);
	}

	private void removeCache(String identity, String bizTypeName) {
		defaultCache.delete(ValidateCodePrefix + bizTypeName + "_" + identity);
	}

	private void doSend(SendTypeEnum sendTypeEnum, String identity,
			String content, String subject) {
		if (sendTypeEnum == SendTypeEnum.SMS) {
			sendSMS(identity, content);
		} else {
			sendEmail(identity, content, subject);
		}
	}

	private void sendSMS(String mobile, String content) {
	//	System.out.println("mobile:" + content);
		logger.info("sms send,mobile=" + mobile + "content=" + content);
	//	SMSService.sendSMS(mobile, content);
		try {
			sMSCodeService.sendSms(mobile, content);
		} catch (IOException e) {
			logger.error("",e);
		}
	}

	private void sendEmail(String email, String content, String subject) {
		/*
		 * System.out.println("email:"+content); EmailSender emailSender = new
		 * EmailSender(true); try { emailSender.sendEmail(Arrays.asList(email),
		 * subject, content); } catch (EmailException e) {
		 * logger.error("邮箱发送失败，email="+email); e.printStackTrace(); }
		 */
		//SendCloudMail.send(email, subject, content);
	}

	private String createMobileCode() {
		int number = new Random().nextInt(1000000);
		String str1 = String.format("%06d", number);
		return str1;
	}

	private String createEmailCode() {
		int number = new Random().nextInt(1000000);
		String str1 = String.format("%06d", number);
		return str1;
	}

	public static void main(String[] args) {
		String contentTemplate = ValidateCodeSend.BizTypeEnum.MailBindEmail
				.getContent();
		// System.out.println(contentTemplate);
		// String contentTemplate = "abcccc#{checkCode}";
		System.out.println(contentTemplate);
		String content = contentTemplate.replaceFirst("#\\{checkCode\\}",
				"12345");
		System.out.println(content);
	}

	public String createExtralCacheCode(String identity){
		String randomNumber= createRandomNumber();
		defaultCache.add(identity, randomNumber, 120);
		return randomNumber;
	}
	
	public boolean checkExtralCacheCode(String identity,String code){
		Object o =defaultCache.getValue(identity);
		if(o!=null){
			defaultCache.delete(identity);
			return true;
		}
		return false;
	}
	
	private String createRandomNumber(){
		int number = new Random().nextInt(1000000);
		String str1 = String.format("%06d", number);
		return str1;
	}
}
